﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Entities</title>
<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
<style type="text/css">
.auto-style2 {
	font-weight: normal;
}
</style>
</head>

<body>

<ul>
	<li><a href="#DocNugetPackage">Nuget package</a></li>
	<li><a href="#DocDbContext">Creating DbContext</a></li>
	<li><a href="#DocRepositories">Repositories</a><ul>
		<li><a href="#DocAppBaseRepo">Application specific base repository class</a></li>
		<li><a href="#DocImplRepositories">Implementing a repository</a></li>
		<li><a href="#DocCustomRepositoryMethods">Custom repository methods</a></li>
	</ul>
	</li>
	<li><a href="#DocSeeAlso">See also</a></li>
</ul>

<p>ASP.NET Boilerplate can work with any O/RM framework. It has built-in 
integration with <b>EntityFramework</b>. This document will explain how to 
use EntityFramework with ASP.NET Boilerplate. It's assumed that you're already familar with 
EntityFramework in a 
basic level.</p>
<h3 id="DocNugetPackage">Nuget package</h3>
<p>Nuget package to use EntityFramework as O/RM in ASP.NET Boilerplate is
<a href="http://www.nuget.org/packages/Abp.EntityFramework" target="_blank">Abp.EntityFramework</a>. You should add it to your application. It's 
better to implement EntityFramework in a seperated assembly (dll) in your application 
and depend on that package from this assembly.</p>
<h3 id="DocDbContext">Creating DbContext</h3>
<p>As you know, to work with EntityFramework, you should define a <strong>DbContext</strong> 
class for your application. An example DbContext is shown below:</p>
<pre lang="cs">public class SimpleTaskSystemDbContext : AbpDbContext
{
    public virtual IDbSet&lt;Person&gt; People { get; set; }
    public virtual IDbSet&lt;Task&gt; Tasks { get; set; }

    public SimpleTaskSystemDbContext()
        : base(&quot;MyConnectionStringName&quot;)
    {
        
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity&lt;Person&gt;().ToTable(&quot;StsPeople&quot;);
        modelBuilder.Entity&lt;Task&gt;().ToTable(&quot;StsTasks&quot;).HasOptional(t =&gt; t.AssignedPerson);
    }
}</pre>
<p>It's a regular DbContext class except it's derived from <strong>AbpDbContext</strong> 
instead of DbContext. There are many overloaded constructors of AbpDbContext. 
You can use which you need.</p>
<p>EntityFramework can map classes to database tables in a 
conventional way. You even don't need to make any configuration unless you make 
some custom stuff. In this example, we mapped entities to different tables. As 
default, Task entity maps to <strong>Tasks</strong> table. But we changed it to 
be <strong>StsTasks</strong> table. Instead of configuring it with data 
annotation attributes, I prefered to use fluent configuration. You can choice 
the way you like.</p>

<h3 id="DocRepositories">Repositories</h3>
<p>ASP.NET Boilerplate provides a base class <strong>EfRepositoryBase</strong> 
to implement repositories easily. To implement IRepository interface, you can 
just derive your repository from this class. But it's better to create your own 
base class that extens EfRepositoryBase. Thus, you can add shared/common methods 
to your repositories easily. </p>
<h4 id="DocAppBaseRepo">Application specific base repository class</h4>
<p>An example base class all for repositories of a SimpleTaskSystem application:</p>
<pre lang="cs">//Base class for all repositories in my application
public class SimpleTaskSystemRepositoryBase&lt;TEntity, TPrimaryKey&gt; : EfRepositoryBase&lt;SimpleTaskSystemDbContext, TEntity, TPrimaryKey&gt;
    where TEntity : class, IEntity&lt;TPrimaryKey&gt;
{
    public SimpleTaskSystemRepositoryBase(IDbContextProvider&lt;SimpleTaskSystemDbContext&gt; dbContextProvider)
        : base(dbContextProvider)
    {
    }

    //add common methods for all repositories
}

//A shortcut for entities those have integer Id
public class SimpleTaskSystemRepositoryBase&lt;TEntity&gt; : SimpleTaskSystemRepositoryBase&lt;TEntity, int&gt;
    where TEntity : class, IEntity&lt;int&gt;
{
    public SimpleTaskSystemRepositoryBase(IDbContextProvider&lt;SimpleTaskSystemDbContext&gt; dbContextProvider)
        : base(dbContextProvider)
    {
    }

    //do not add any method here, add to the class above (because this class inherits it)
}</pre>
<p>Notice that we're inheriting from EfRepositoryBase&lt;<strong>SimpleTaskSystemDbContext</strong>, TEntity, TPrimaryKey&gt;. 
This declares ASP.NET Boilerplate to use SimpleTaskSystemDbContext in our 
repositories.</p>
<h4 id="DocImplRepositories">Default repository implementation</h4>
<p>You don't have to create repository classes for entities to just use 
predefined repository methods. Example:</p>
<pre lang="cs">public class PersonAppService : IPersonAppService
{
    private readonly IRepository&lt;Person&gt; _personRepository;

    public PersonAppService(IRepository&lt;Person&gt; personRepository)
    {
        _personRepository = personRepository;
    }

    public void CreatePerson(CreatePersonInput input)
    {        
        person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
        
        _personRepository.Insert(person);
    }
}</pre>

<p>PersonAppService contructor-injects <strong>IRepository&lt;Person&gt;</strong> and 
uses the <strong>Insert</strong> method. In this way, you can easily inject
<strong>IRepository&lt;TEntity&gt;</strong> (or IRepository&lt;TEntity, TPrimaryKey&gt;) and 
use predefined methods. See <a href="/Pages/Documents/Repositories">repository 
documentation</a> for list of all predefined methods.</p>

<h4 id="DocCustomRepositoryMethods">Custom repositories</h4>
<p>To implement a custom repository, just derive from your application specific 
base repository class we created above.</p>
<p>Assume that we have a Task entity that can be assigned to a Person (entity) 
and a Task has a State (new, assigned, completed... and so on). We may need to 
write a custom method to get list of Tasks with some conditions and with 
AssisgnedPerson property pre-fetched (included) in a single database query. See the example 
code:</p>
<pre>public interface ITaskRepository : IRepository&lt;Task, long&gt;
{
    List&lt;Task&gt; GetAllWithPeople(int? assignedPersonId, TaskState? state);
}

public class TaskRepository : SimpleTaskSystemRepositoryBase&lt;Task, long&gt;, ITaskRepository
{
    public TaskRepository(IDbContextProvider&lt;SimpleTaskSystemDbContext&gt; dbContextProvider)
        : base(dbContextProvider)
    {
    }

    public List&lt;Task&gt; GetAllWithPeople(int? assignedPersonId, TaskState? state)
    {
        var query = GetAll();

        if (assignedPersonId.HasValue)
        {
            query = query.Where(task =&gt; task.AssignedPerson.Id == assignedPersonId.Value);
        }

        if (state.HasValue)
        {
            query = query.Where(task =&gt; task.State == state);
        }

        return query
            .OrderByDescending(task =&gt; task.CreationTime)
            .Include(task =&gt; task.AssignedPerson)
            .ToList();
    }
}</pre>
<p><strong class="auto-style2">We first defined </strong>ITaskRepository and 
then implemented it.<strong> GetAll()</strong> returns <strong>IQueryable&lt;Task&gt;</strong>, then we can add some
<strong>Where</strong> filters using given parameters. Finally we can call
<strong>ToList()</strong> to get list of 
Tasks.</p>
<p>You can also use <strong>Context </strong>object in repository methods to 
reach to your DbContext and directly use Entity Framework infrastructure.</p>
<p>A repository should get a IDbContextProvider in it's repository. In this way, 
we can easily inject a fake DbContext provider in unit tests. In runtime, 
ASP.NET Boilerplate automatically injects the right DbContext provider.</p>

<h3 id="DocSeeAlso">See also</h3>
<p>See <a href="/Pages/Documents/Repositories">repository documentation</a> 
for more information on repositories.</p>

</body>

</html>
